'-------------------------------------------------------------------------
' Wiznet W5100 Micromite Examples
'
' Hardware Connections
'
' +--------+--------------------------------------------+
' | Wiznet | Micromite                                  |
' +--------+--------------------------------------------+
' | Ground |  Pin 19                                    |
' | +5V    |  +5V                                       |
' | RST    |  Pin 23 (Wiznet W5100 Reset)               |
' | SS     |  Pin 15 (SPI Slave Select)                 |
' | CLK    |  Pin 25 (SPI Clock)                        |
' | MO     |  Pin 3 (SPI MOSI - Master Out, Slave In)   |
' | MI     |  Pin 14 (SPI MISO - Master In, Slave Out)  |
' | Gnd    |  not used                                  |
' | PoE+   |  not used                                  |
' | PoE-   |  not used                                  |
' +--------+--------------------------------------------+

Option explicit
Option base 1

dim ip1%, ip2%, ip3%, ip4%
Dim example$
Dim txstring$
Dim curLineBlank%, curFirstLine%
Dim char%
Dim firstLine$
Dim i%
Dim conversationStart%
settick 1000, toggle2
setpin 2,dout
pin(2)=0

RTC GETTIME

' Call with pin used for Wiznet Reset and SPI Slave Select of Wiznet:
WN.Init 23, 15

' Set a pin as analog input for testing webserver
SetPin 26, ain

' Set up the IP address to use
ip1%=10
ip2%=0
ip3%=0
ip4%=158

' Set static MAC address/IP address/subnet mask/gateway

WN.SetMAC &H00,&HFE,ip1%,ip2%,ip3%,ip4%
WN.SetIP ip1%,ip2%,ip3%,ip4%
WN.SetMask 255,255,255,0
WN.SetGateway ip1%,ip2%,ip3%,138

WN.Start    ' Sets various internal registers for Wiznet

Do
  If WN.SockClosed(3) Then
    If WN.SockTCPInit(3, 80) Then
      Print "Socket initialized on local port 80"
    Else
      Error "Failed to initialize socket"
    End If
    If WN.SockTCPListen(3) Then
      Print "Server is at "+WN.GetIP$()
      curLineBlank%=1
      curFirstLine%=1
      firstLine$=""
      conversationStart%=0
    Else
      Error "Failed to listen on socket"
    End If
  End If

  Do While WN.SockEstablished(3)
    If conversationStart%=0 Then conversationStart%=Timer
    For i%=1 To WN.sockData(3)
      char%=WN.sockRead(3)
      Print Chr$(char%);
      If char%=&H0D Then
        If curLineBlank%=1 Then
          Print firstLine$
                    WN.SockWrite 3,"HTTP/1.1 200 OK"+WN_CrLf$
          WN.SockWrite 3,"Content-Type: text/html"+WN_CrLf$
          WN.SockWrite 3,""+WN_CrLf$
          WN.SockWrite 3,"<!DOCTYPE HTML>"+WN_CrLf$
          WN.SockWrite 3,"<html>"+WN_CrLf$
          WN.SockWrite 3,"<h1>BIGMIK's Micromite Webserver</h1>"+WN_CrLf$
          
          WN.SockWrite 3," <img src=http://tinyurl.com/pxguu2n>" +WN_CrLf$
                    
                    
          WN.SockWrite 3,"<h3>Micromite Date & Time (NOT Accurate to the second)</h3>" + Date$ + "      " + time$+WN_CrLf$
          WN.SockWrite 3,"<h3>ANALOG Read Pin(26) of the MicroMite</h3>" +WN_CrLf$
                    
          WN.SockWrite 3,"<p>Pin 26: (50% duty cycle)  ="+Str$(Pin(26))+" volts</p>"+WN_CrLf$
          WN.SockWrite 3,"<h3>My Beautiful Daughter's very first time soldering an electronic clock kit</h3>"+WN_CrLf$
          
          WN.SockWrite 3," <img src=http://www.thebackshed.com/forum/uploads/bigmik/2015-01-29_060916_Georgia_Clock.jpg>" +WN_CrLf$

                              
          WN.SockWrite 3,"<h3>Various MicroMite Links</h3>"+WN_CrLf$
                                                            
          WN.SockWrite 3,"<a href=http://www.thebackshed.com/forum/forum_topics.asp?FID=16>The Back Shed Forum"
          WN.SockWrite 3,"<h3></h3>" +WN_CrLf$

          WN.SockWrite 3,"<a href=http://www.dontronics.com/micks-mites/files/>A Directory of BIGMIK's PCBs etc"
          WN.SockWrite 3,"<h3></h3>" +WN_CrLf$
          WN.SockWrite 3,"<a href=http://www.dontronics.com>My old Mate and Drinking Buddie's Home page" 
          WN.SockWrite 3,"<h3></h3>" +WN_CrLf$
          WN.SockWrite 3,"<a href=http://www.geoffg.net/>Geoff Graham's wonderful MicroMite and Maximite Home Page"
          WN.SockWrite 3,"<h3></h3>" +WN_CrLf$
          WN.SockWrite 3,"<a href=http://www.wunderground.com/weather-forecast/zmw:00000.1.94866?MR=1/>MELBOURNE Weather"
          WN.SockWrite 3,"<h3></h3>" +WN_CrLf$
          WN.SockWrite 3,"</html>"+WN_CrLf$
          WN.SockWrite 3,""+WN_CrLf$
                    
                    
                                        
                                        
                                        
                                        
          WN.SockClose 3
        End If
      End If
      If char%=&H0D Then
        curLineBlank%=1
        curFirstLine%=0
      Else If char%<>&H0A Then
        curLineBlank%=-1
        If curFirstLine%=1 Then
          firstLine$=firstLine$+Chr$(char%)
        End If
      End If
    Next i%
  Loop
  If conversationStart%>0 Then
    Print "Time: "+Str$((Timer-conversationStart%)/1000)+" seconds"
    conversationStart%=0
  End If
Loop

End

'-------------------------------------------------------------------------
' WIZNET W5100 Subs and Functions

Sub WN.Init(resetPin%, slaveSelectPin%)
  dim integer WN_OptionBase=1       ' Set to match option base above (if changed)
  dim WN_CrLf$=Chr$(&H0D)+Chr$(&H0A)
  dim WN_SPISpeed%=1000000 '10000000 is max that works
  DIM WN_ResetPin%=resetPin%
  DIM WN_SSPin%=slaveSelectPin%

  ' Set the slave select pin HIGH and to output pin
  Pin(WN_SSPin%)=1
  SetPin WN_SSPin%, dout

  SetPin WN_ResetPin%, dout
  Pin(resetPin%)=0
  ' Wiznet docs: assert low for 2us to reset Wiznet
  Pause 10 ' we wait 10 milliseconds
  Pin(resetPin%)=1
End Sub

Sub WN.Close()
  PIN(WN_SSPin%)=0
  SETPIN WN_SSPin%,OFF
  PIN(WN_ResetPin%)=0  
  SETPIN WN_ResetPin%,OFF
END SUB
  
Sub WN.Start()
  WN.Write(0, 0, &B00000000) ' Mode Register, enable ping
  WN.Write(0, &H16, &B00000000) ' Interrupt Mask Register
  WN.Write(0, &H17, &H0F) ' Retry time value high (400ms)
  WN.Write(0, &H18, &HA0) ' Retry time value low (400ms)
  WN.Write(0, &H19, &H08) ' retry count register
  WN.Write(0, &H1A, &B01010101) ' RX Memory Size (2KB/socket)
  WN.Write(0, &H1B, &B01010101) ' TX Memory Size (2KB/socket)
End Sub
  
Function WN.Read(addrHi%, addrLo%)
  Local junk%
  Pin(WN_SSPin%)=0
  SPI open WN_SPISpeed%, 0, 8
  junk%=SPI(&H0F)
  junk%=SPI(addrHi%)
  junk%=SPI(addrLo%)
  WN.Read=SPI(0)
  Pin(WN_SSPin%)=1
  SPI close
End Function
  
Sub WN.Write(addrHi%, addrLo%, writeData%)
  Local junk%
  Pin(WN_SSPin%)=0
  SPI open WN_SPISpeed%, 0, 8
  junk%=SPI(&HF0)
  junk%=SPI(addrHi%)
  junk%=SPI(addrLo%)
  junk%=SPI(writeData%)
  Pin(WN_SSPin%)=1
  SPI close
End Sub
  
Sub WN.SetGateway (oct1%, oct2%, oct3%, oct4%)
  WN.Write(&H00, &H01, oct1%)
  WN.Write(&H00, &H02, oct2%)
  WN.Write(&H00, &H03, oct3%)
  WN.Write(&H00, &H04, oct4%)
End Sub
  
Sub WN.SetMask (oct1%, oct2%, oct3%, oct4%)
  WN.Write(&H00, &H05, oct1%)
  WN.Write(&H00, &H06, oct2%)
  WN.Write(&H00, &H07, oct3%)
  WN.Write(&H00, &H08, oct4%)
End Sub
  
Sub WN.SetMAC (oct1%, oct2%, oct3%, oct4%, oct5%, oct6%)
  WN.Write(&H00, &H09, oct1%)
  WN.Write(&H00, &H0A, oct2%)
  WN.Write(&H00, &H0B, oct3%)
  WN.Write(&H00, &H0C, oct4%)
  WN.Write(&H00, &H0D, oct5%)
  WN.Write(&H00, &H0E, oct6%)
End Sub
  
Sub WN.SetIP (oct1%, oct2%, oct3%, oct4%)
  WN.Write(&H00, &H0F, oct1%)
  WN.Write(&H00, &H10, oct2%)
  WN.Write(&H00, &H11, oct3%)
  WN.Write(&H00, &H12, oct4%)
End Sub
  
Function WN.GetIP$()
  Local oct1%, oct2%, oct3%, oct4%
  oct1%=WN.Read(&H00, &H0F)
  oct2%=WN.Read(&H00, &H10)
  oct3%=WN.Read(&H00, &H11)
  oct4%=WN.Read(&H00, &H12)
  WN.GetIP$=Str$(oct1%)+"."+Str$(oct2%)+"."+Str$(oct3%)+"."+Str$(oct4%)
End Function
  
Function WN.SockTCPInit(socket%, srcport%)
  WN.Write(socket%+4, &H00, &H01) 'Sn_MR Mode Register
  WN.Write(socket%+4, &H04, srcport% >> 8) 'Sn_PORT Source Port Hi
  WN.Write(socket%+4, &H05, srcport% And &HFF) 'Sn_PORT Source Port Lo
  WN.Write(socket%+4, &H01, &H01) 'Sn_CR Command Register, Open
  'Sn_SR Status Register
  If WN.Read(socket%+4, &H03)<>&H13 Then
    'Failed to init socket
    WN.SockTCPInit=0
    WN.Write(socket%+4, &H01, &H10) 'Sn_CR Command Register, Close
  Else
    WN.SockTCPInit=1
  End If
End Function
  
Function WN.SockUDPInit(socket%, srcport%)
  WN.Write(socket%+4, &H00, &H02) 'Sn_MR Mode Register
  WN.Write(socket%+4, &H04, srcport% >> 8) 'Sn_PORT Source Port Hi
  WN.Write(socket%+4, &H05, srcport% And &HFF) 'Sn_PORT Source Port Lo
  WN.Write(socket%+4, &H01, &H01) 'Sn_CR Command Register, Open
  'Sn_SR Status Register
  If WN.Read(socket%+4, &H03)<>&H22 Then
    'Failed to init socket
    WN.SockUDPInit=0
    WN.Write(socket%+4, &H01, &H10) 'Sn_CR Command Register, Close
  Else
    WN.SockUDPInit=1
  End If
End Function
  
Function WN.SockTCPListen(socket%)
  WN.Write(socket%+4, &H01, &H02) 'Sn_CR Command Register, Listen
  'Sn_SR Status Register
  If WN.Read(socket%+4, &H03)<>&H14 Then
    'Failed to listen
    WN.SockTCPListen=0
    WN.Write(socket%+4, &H01, &H10) 'Sn_CR Command Register, Close
  Else
    WN.SockTCPListen=1
  End If
End Function
  
Sub WN.SockClose(socket%)
  WN.Write(socket%+4, &H01, &H08) 'Sn_CR Command Register, DISCON
End Sub
  
Function WN.SockEstablished(socket%)
  Local SnCR%
  SnCR%=WN.Read(socket%+4, &H03)
  If SnCR%=&H1C Then
    WN.Write(socket%+4, &H01, &H08) 'Sn_CR Command Register, DISCON
  End If
  If SnCR%=&H17 Then
    WN.SockEstablished=1
  Else
    WN.SockEstablished=0
  End If
End Function
  
Function WN.SockClosed(socket%)
  Local SnCR%
  SnCR%=WN.Read(socket%+4, &H03)
  If SnCR%=&H00 Then
    WN.SockClosed=1
  Else
    WN.SockClosed=0
  End If
End Function
  
Function WN.SockData(socket%)
  WN.SockData=(WN.Read(socket%+4, &H26)*256)+(WN.Read(socket%+4, &H27))
End Function
  
Function WN.SockRead(socket%)
  Local SnRXRead%, offset%, address%
  SnRXRead%=(WN.Read(socket%+4, &H28)*256)+(WN.Read(socket%+4, &H29))
  offset%=SnRXRead% And &H07FF
  address%=&H6000+(socket%*&H800)+offset%
  WN.SockRead=WN.Read(address% >> 8, address% And &HFF) 'readbyte
  SnRXRead%=SnRXRead%+1
  If SnRXRead%>65535 Then SnRXRead%=0
  WN.Write(socket%+4, &H28, SnRXRead% >> 8) 'increment counter
  WN.Write(socket%+4, &H29, SnRXRead% And &HFF)
  WN.Write(socket%+4, &H01, &H40) 'Sn_CR Command Register, RECV
End Function
  
SUB WN.SockUDPDest (socket%, doct1%, doct2%, doct3%, doct4%, dstport%)
  WN.Write(socket%+4, &H0C, doct1%)
  WN.Write(socket%+4, &H0D, doct2%)
  WN.Write(socket%+4, &H0E, doct3%)
  WN.Write(socket%+4, &H0F, doct4%)
  WN.Write(socket%+4, &H10, dstport% >> 8) 'Sn_PORT Source Port Hi
  WN.Write(socket%+4, &H11, dstport% And &HFF) 'Sn_PORT Source Port Lo
END SUB
  
Sub WN.SockWrite(socket%, sockTX$)
  Local TXchars%, SnTXFSR%, SnTXWR%, offset%, address%, i%
  TXchars%=Len(sockTX$)
waitforprocessing:
  SnTXFSR%=(WN.Read(socket%+4, &H20)*256)+(WN.Read(socket%+4, &H21))
  If SnTXFSR%<TXchars% Then GoTo waitforprocessing
  SnTXWR%=(WN.Read(socket%+4, &H24)*256)+(WN.Read(socket%+4, &H25))
  offset%=SnTXWR% And &H07FF
  address%=&H4000+(socket%*&H800)+offset%
  For i%=1 To TXchars%
    If address%>&H4000+(socket%*&H800)+&H7FF Then address%=address%-&H800
    WN.Write(address%>>8, address% And &HFF, Asc(Mid$(sockTX$, i%, 1)))
    address%=address%+1
  Next i%
  SnTXWR%=SnTXWR%+TXchars%
  If SnTXWR%>65535 Then SnTXWR%=SnTXWR%-65536
  WN.Write(socket%+4, &H24, SnTXWR% >> 8)
  WN.Write(socket%+4, &H25, SnTXWR% And &HFF)
  WN.Write(socket%+4, &H01, &H20) 'Sn_CR Command Register, SEND
End Sub
  
Function WN.SockTCPConnect(socket%, oct1%, oct2%, oct3%, oct4%, destport%)
  Local timerstart%, SnCR%
  WN.Write(socket%+4, &H0C, oct1%) 'Destination IP Address
  WN.Write(socket%+4, &H0D, oct2%)
  WN.Write(socket%+4, &H0E, oct3%)
  WN.Write(socket%+4, &H0F, oct4%)
  WN.Write(socket%+4, &H10, (destport% >> 8) 'Sn_DPORT Hi
  WN.Write(socket%+4, &H11, destport% And &HFF) ' Lo
  WN.Write(socket%+4, &H01, &H04) 'Sn_CR Command Register, Connect
  WN.SockTCPConnect=0
  timerstart% = Timer
  Do While (Timer - timerstart%)<4000 ' Wait at least 4 seconds for connection
    SnCR%=WN.Read(socket%+4, &H03)
    If SnCR%=&H17 Then ' Established
      WN.SockTCPConnect=1
      Exit Do
    Else If SnCR%=&H00 Then ' Closed (Timeout connecting)
      Exit Do
    End If
  Loop
End Function

toggle2:
pin(2)=not(pin(2))
ireturn

